package com.hmdp.filter;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.hmdp.dto.UserDTO;
import com.hmdp.entity.User;
import com.hmdp.utils.JwtUtil;
import com.hmdp.utils.UserHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;

import javax.annotation.Resource;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import static com.hmdp.utils.RedisConstants.INVALID_JWT_KEY;

/**
 * @Author lxh
 * @Date 2022/8/2
 * @Date 9:06
 * @Version 1.0
 */
@Slf4j
@WebFilter(urlPatterns = "/*",filterName = "jwtLoginFilter")
public class JwtLoginFilter implements Filter {
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    private static final Set<String> ALLOWED_PATHS = Collections.unmodifiableSet(new HashSet<>(
            Arrays.asList(
                    "/shop/**",
                    "/voucher/**",
                    "/shop-type/**",
                    "/upload/**",
                    "/blog/hot",
                    "/user/code",
                    "/user/login")));
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.debug("jwt登陆过滤器初始化...");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest req=(HttpServletRequest) servletRequest;
        String path = req.getRequestURI().substring(req.getContextPath().length())
                .replaceAll("[/]+$", "");
        if(!ALLOWED_PATHS.contains(path)) {
            HttpServletResponse response = (HttpServletResponse) servletResponse;
            String jwt = req.getHeader("authorization");
            if(StrUtil.isBlank(jwt)){
                //不存在拦截直接放行
                response.setStatus(401);
                return;
            }
            //判断jwt是否无效
            String value = stringRedisTemplate.opsForValue().get(INVALID_JWT_KEY + jwt);
            if(value!=null){
                log.debug("token失效！");
                response.setStatus(401);
                return;
            }
            //jwt解码，获取数据
            UserDTO userDTO = JwtUtil.jwtDecode(jwt, UserDTO.class);
            if(userDTO==null){
                //拦截
                response.setStatus(401);
                return;
            }
            //UserDTO放到ThreadLocal中
            UserHolder.saveUser(userDTO);
        }
        //放行
        log.debug("放行");
        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {
        log.info("jwt过滤器销毁...");
    }
}
